package com.itgacl.magic4j.libcommon.component.ws;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.time.LocalDateTime;

/**
 * websocket消息处理器
 */
@Slf4j
@ConditionalOnProperty(prefix = "ws", value = "enable", havingValue = "true")
@Component
public class WsHandler extends AbstractWebSocketHandler {

    @Autowired
    private WsService wsService;

    /**
     * socket 建立成功事件
     *
     * @param session
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        log.debug("建立ws连接");
        Object clientId = session.getAttributes().get("clientId");
        if (clientId != null) {
            // 用户连接成功，放入在线用户缓存
            WsSessionManager.add(clientId.toString(), session);
        } else {
            throw new RuntimeException("用户登录已经失效!");
        }
    }

    /**
     * 接收消息事件
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 获得客户端传来的文本消息
        String payload = message.getPayload();
        Object clientId = session.getAttributes().get("clientId");
        log.debug("server 接收到 " + clientId + " 发送的 " + payload);
        String sendMsg = "server 给 " + clientId + " 发送消息： " + payload + " " + LocalDateTime.now().toString();
        //发送消息到客户端
        wsService.sendMsg(session, sendMsg);
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
        log.debug("发送二进制消息");
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        WsSessionManager.removeAndClose(session.getId());
        log.error("异常处理：" + exception.getMessage(), exception);
    }

    /**
     * socket 断开连接时
     *
     * @param session
     * @param status
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        log.debug("关闭ws连接");
        Object clientId = session.getAttributes().get("clientId");
        if (clientId != null) {
            // 用户退出，移除缓存
            WsSessionManager.remove(clientId.toString());
        }
    }
}
